/*
 * Holder.h
 *
 *  Created on: 2011-12-1
 *      Author: Lucifer
 */

#ifndef __BFX_HOLDER_H__
#define __BFX_HOLDER_H__

namespace BFX
{

//////////////////////////////////////////////////////////////////////////////

template <typename TYPE, void (*ACQUIREF)(TYPE), void (*RELEASEF)(TYPE)>
class BFX_TMPL HolderT
{
protected:
	TYPE	m_value;
	bool	m_bAcquired;		// Have we acquired the resource?

public:
	HolderT(TYPE value, bool bTake = true) :
			m_value(value), m_bAcquired(false)
	{
		if (bTake)
			Acquire();
	}
	virtual ~HolderT()
	{
		Release();
	}
	void Acquire()
	{
		BFX_ASSERT(!m_bAcquired);

		ACQUIREF(m_value);
		m_bAcquired = true;
	}
	void Release()
	{
		if (m_bAcquired)
		{
			RELEASEF(m_value);
			m_bAcquired = false;
		}
	}

private:
	HolderT<TYPE, ACQUIREF, RELEASEF>& operator=(const HolderT<TYPE, ACQUIREF, RELEASEF> &holder)
	{
		BFX_ASSERT(0);	// No assignment allowed
		return (*this);
	}
	HolderT(const HolderT<TYPE, ACQUIREF, RELEASEF> &holder)
	{
		m_bAcquired = false;
		BFX_ASSERT(0);	// No copy construction allowed
	}
};

//////////////////////////////////////////////////////////////////////////////

template <typename TYPE, void (TYPE::*ACQUIREF)(), void (TYPE::*RELEASEF)()>
class BFX_TMPL ObjectHolderT
{
protected:
	TYPE*	m_value;
	bool	m_bAcquired;		// Have we acquired the resource?

public:
	ObjectHolderT(TYPE* value, bool bTake = true) :
			m_value((TYPE*)value), m_bAcquired(false)
	{
		if (bTake)
			Acquire();
	}
	virtual ~ObjectHolderT()
	{
		Release();
	}
	void Acquire()
	{
		BFX_ASSERT(!m_bAcquired);

		(m_value->*ACQUIREF)();
		m_bAcquired = true;
	}
	void Release()
	{
		if (m_bAcquired)
		{
			(m_value->*RELEASEF)();
			m_bAcquired = false;
		}
	}

private:
	ObjectHolderT<TYPE, ACQUIREF, RELEASEF>& operator=(const ObjectHolderT<TYPE, ACQUIREF, RELEASEF> &holder)
	{
		BFX_ASSERT(0);	// No assignment allowed
		return (*this);
	}
	ObjectHolderT(const ObjectHolderT<TYPE, ACQUIREF, RELEASEF> &holder)
	{
		m_value = NULL;
		m_bAcquired = false;
		BFX_ASSERT(0);	// No copy construction allowed
	}
};

} /* namespace BFX */

#endif /* __BFX_HOLDER_H__ */
